home *** CD-ROM | disk | FTP | other *** search
- _A BRIEF MACRO PACKAGE FOR EDITING BINARY FILES_
- by James Rodriguez
-
-
- [LISTING ONE]
-
- /¬ _ini⌠ _hex_edi⌠ _bin_oε _bin_ofµ _bin_mousσ write_buffe≥ */
-
- #define HEX
-
- #define SHOW_DELAY 50
- #define UP -11
- #define DOWN 11
- #define LEFT -1
- #define RIGHT 1
- #define PGUP -21
- #define PGDN 21
- #define TOP 30
- #define BOTTOM -31
- #define HOME -40
- #define END -41
-
- extern _package_buf, delete_curr_buffer;
-
- int __hex_files, __bin_keyboard, __hex_window, __asc_window, __unix_files;
- _init ()
- { __hex_files = create_buffer ("HEXFILES", NULL, 1); //Binary file database
- __unix_files = create_buffer ("UNIXFILE", NULL, 1); //Unix file database
- register_macro (6, "_bin_edit");
- keyboard_push (); // Create a new keyboard
- set_mouse_action("_bin_mouse"); // Define the mouse handler
- add_hex_keys(); // Add key assignments
- __bin_keyboard = inq_keyboard (); // Store the keyboard identifier
- keyboard_pop (1); // Reset the stack
- }
- // _hex_edit: associates a system buffer with a hex buffer and modifies
- // the package information for .HEX files. Called by _bin_edit.
- void _hex_edit (string file_name, int in_memory)
- { int __hex_buffer, __asc_buffer, tmp_buf, current_buffer;
- string buffer_name, file_ext, buffer_id, file_path;
- global __hex_buffer, __asc_buffer;
-
- if (get_parm (0, file_name))
- { get_parm (1, in_memory); // Check any flag passed
- if (index (file_name, "."))
- { file_ext = substr (file_name, 1 + rindex (file_name, "."));
- file_name = substr (file_name, 1, rindex (file_name, ".") - 1);
- }
- else file_ext = "";
- buffer_name = substr (file_name, rindex (file_name, "\\") + 1);
- current_buffer = inq_buffer ();
- if (inq_called () == "_bin_edit")
- delete_buffer (current_buffer);
- // Error check for bad buffer name
- tmp_buf = create_buffer (buffer_name + ".hex", file_name + ".hex", 0);
- if (tmp_buf)
- { set_buffer (__hex_files);
- top_of_buffer ();
- if (search_fwd (file_name + ",", 0, 0))
- edit_file (file_name + ".hex"); // It's already in a buffer
- else
- { delete_buffer (tmp_buf);
- sprintf (file_path, "bbe BH %s.%s %s.hex %s.asc>&nul", file_name,
- file_ext, file_name, file_name);
- // Do the hex files already exist?
- if (!exist (file_name + ".hex") && !exist (file_name + ".asc"))
- { message ("Generating hex file");
- dos (file_path); // spawn standalone program to convert file
- }
- else
- message ("Editing existing files.");
- __hex_buffer = create_buffer (buffer_name + ".hex", file_name +
- ".hex", 0);
- __asc_buffer = create_buffer (buffer_name + ("." + file_ext),
- file_name + ".asc", 1);
- // Save info in the database for later.
- sprintf (buffer_id, "oldb=%10d,newb=%10d,file=%s,ext=%s",
- __hex_buffer, __asc_buffer, file_name, file_ext);
- set_buffer (__hex_files);
- beginning_of_line ();
- insert (buffer_id + "\n");
- set_buffer (__hex_buffer);
- top_of_buffer ();
- drop_anchor ();
- move_rel (0, 1);
- // Access the package buffer and configure for the hex extension.
- if (first_time ())
- { if (!_package_buf) load_macro ("language");
- set_buffer (_package_buf);
- top_of_buffer ();
- while (search_fwd ("<.hex", 1, 0))
- delete_line ();
- // Add the correct lines in packages to make this work.
- insert (".hex_equivalents\n");
- insert (".hex_new;\n");
- insert (".hex_existing;\n");
- insert (".hex_first;\n");
- insert (".hex_on;_on,_bin_on\n"); // Enabled _bin_on
- insert (".hex;=hex,,=hex\n");
- top_of_buffer ();
- }
- set_buffer (__hex_buffer);
- if (! in_memory)
- call_registered_macro (1);
- }
- }
- }
- }
- // _bin_on: edits the hex and ascii files in side by side windows by creating
- // and moving an edge. Insures correct local keyboard by setting it explicitly.
- // Looks in hex_files buffer for filename and extract buffer ids. Associate
- // buffers with windows and return.
- string _bin_on ()
- { int i;
- string buf_to_find, exten;
- inq_names (buf_to_find, exten);
- buf_to_find = substr (buf_to_find, 1, (rindex (buf_to_find, exten) -
- strlen (exten)) + 1);
- i = inq_buffer();
- set_buffer (__hex_files); // Edit the system buffer to find buffer id's.
- top_of_buffer ();
- if (search_fwd (buf_to_find + ",", 0, 0)) // Find the line with filename.
- {
- keyboard_flush(); // Remove any pending keystrokes
- use_local_keyboard (0); // Detach the local keyboard
- keyboard_push (__bin_keyboard); // Activate the hex keyboard
- set_mouse_action("_bin_mouse"); // Attach the mouse event handler
- beginning_of_line ();
- buf_to_find = trim (read ()); // Parse out the buffer ids
- buf_to_find = ltrim (substr (buf_to_find, index (buf_to_find, "oldb=")
- + 5, 10));
- __hex_buffer = atoi (buf_to_find, 1);
- beginning_of_line ();
- buf_to_find = read ();
- buf_to_find = ltrim (substr (buf_to_find, index (buf_to_find, "newb=")
- + 5, 10));
- __asc_buffer = atoi (buf_to_find, 1);
- set_buffer (__hex_buffer);
- // Unregister the registered macro so a recursive situation does not
- // arise from the window manipulations.
- unregister_macro (1, "_call_on_packages");
- create_edge (3);
- __hex_window = inq_window ();
- move_edge (1, 12);
- change_window (1);
- __asc_window = inq_window ();
- attach_buffer (__asc_buffer); // Attach the system buffer to a window
- if (!inq_marked ())
- drop_anchor (2);
- else
- refresh ();
- refresh ();
- change_window (3);
- register_macro (1, "_call_on_packages"); // Enable the language macro.
- returns "_bin_off"; // Return the off event for the language package.
- }
- else
- { set_buffer(i); // This is an error check to allow editing
- returns ""; // of files with .hex extensions which are not
- } // under the binary package control.
- }
- // _bin_off -- deletes the created window and resets the keyboard.
- void _bin_off ()
- { keyboard_flush();
- keyboard_pop ();
- keyboard_push ();
- add_hex_keys();
- __bin_keyboard = inq_keyboard ();
- delete_edge (1); // Delete the window
- keyboard_pop (1);
- set_mouse_action("_mouse_action"); // Reset the mouse handler
- }
- #define BUTTON_1_CLICK 10
- #define BUTTON_2_CLICK 11
- #define BUTTON_1_DBLCLK 13
- #define BUTTON_2_DBLCLK 14
- #define VERTICAL_SCROLL 17
- #define CLOSE_WINDOW 19
- #define SET_WINDOW 20
- #define STATUS_AREA 21
- #define SCROLLBAR__LINEUP 0
- #define SCROLLBAR__LINEDOWN 1
- #define SCROLLBAR__PAGEUP 2
- #define SCROLLBAR__PAGEDOWN 3
- #define SCROLLBAR__TOP 6
- #define SCROLLBAR__BOTTOM 7
- #define TITLE_BAR 1
-
- void _bin_mouse(int action, int modifier, int line, int col)
- { if (inq_window() == __asc_window)
- col = col*2; // Modify the column parameter if clicked in ascii window
- switch (action)
- {
- case STATUS_AREA: // Go to offset on status area click
- execute_macro(inq_assignment("<Alt-g>"));
- case SET_WINDOW: // A different window was selected
- {
- if (col!=TITLE_BAR && line == __asc_window) // Disregard mouse action
- { // on the border.
- unregister_macro (1, "_call_on_packages");
- set_window (__asc_window);
- }
- }
- case BUTTON_2_CLICK:
- case BUTTON_2_DBLCLK:
- case BUTTON_1_CLICK:
- case BUTTON_1_DBLCLK:
- { int lines,cols;
- if (col % 2) // Modify column parameter to event byte value
- col++;
- if (col > 50) // If past formatted string length go to the end of
- col = 50; // the string.
- unregister_macro (1, "_call_on_packages");
- set_window (__hex_window);
- inq_position(lines, cols);
- raise_anchor ();
- move_rel(0,-1);
- save_position();
- if (move_abs(line,col))
- {
- // If beyond the end of buffer ignore the action
- if (! inq_position(lines,cols) && lines==line && cols == col)
- { restore_position(0);
- move_rel(0,-1);
- set_window (__asc_window);
- raise_anchor ();
- move_abs(line,col / 2);
- drop_anchor (2);
- refresh ();
- set_window (__hex_window);
- }
- else
- restore_position();
- }
- else
- restore_position();
- drop_anchor ();
- move_rel (0, 1);
- register_macro (1, "_call_on_packages");
- refresh ();
- switch (action)
- {
- case BUTTON_2_DBLCLK: // Opens a line (feature not shown)
- { execute_macro(inq_assignment("<Ctrl-Enter>"));
- }
- case BUTTON_1_DBLCLK: // Double click modifies current byte.
- { string sread, character;
- int hex_val;
- raise_anchor ();
- move_rel (0, -1);
- sread = "Enter new value for ";
- if (read (1) != "\n")
- sread += read (2);
- sread += ": ";
- if (get_parm (NULL, character, sread, 2))
- { hex_val = _bin_atoh (character);
- sprintf (character, "%02x", hex_val); // Convert int to hex
- unregister_macro (1, "_call_on_packages");
- set_window (__asc_window);
- switch (hex_val) // Make sure the value is displayable.
- { case 13:
- case 9:
- case 0:
- sread = ".";
- default:
- sprintf (sread, "%c", hex_val);
- }
- /* Insert the value in the hex and ascii buffers
- ** rehighlight both windows and return. */
- insert ("%s", sread);
- raise_anchor ();
- delete_char ();
- move_rel (0, -1);
- drop_anchor (2);
- refresh ();
- set_window (__hex_window);
- insert ("%s", upper (character));
- delete_char (2);
- move_rel (0, -2);
- }
- drop_anchor ();
- move_rel (0, 1);
- refresh ();
- register_macro (1, "_call_on_packages");
- refresh ();
- }
- }
- }
- case VERTICAL_SCROLL: // Vertical scroll bar events.
- {
- switch (line)
- {
- case SCROLLBAR__LINEUP: // Click on up arrow
- execute_macro(inq_assignment("<Left>"));
- case SCROLLBAR__LINEDOWN: // Click on down arrow
- execute_macro(inq_assignment("<Right>"));
- case SCROLLBAR__PAGEUP: // Click above thumb button
- execute_macro(inq_assignment("<PgUp>"));
- case SCROLLBAR__PAGEDOWN: // Click below thumb button
- execute_macro(inq_assignment("<PgDn>"));
- case SCROLLBAR__TOP: // Double click on up arrow
- execute_macro(inq_assignment("<Ctrl-PgUp>"));
- case SCROLLBAR__BOTTOM: // Double click on down arrow
- execute_macro(inq_assignment("<Ctrl-PgDn>"));
- }
- }
- }
- }
- // write_buffer: A replacement for write_buffer. Checks file extension, cleans
- // up system buffers. Note: conversion back to binary is not done if buffer
- // has not been modified.
- replacement int write_buffer ()
- {
- int buf_to_edit, buf_to_delete, file_is_controlled, file_was_modified;
- string file_name, ext, response, response2, old_buffer, write_command;
- inq_names (file_name, ext);
- /* if write_buffer was not called from the keyboard and the extension
- ** isn't .hex or .unx call write_buffer. */
- if ("" == inq_called () && (ext == "hex" || ext == "unx"))
- if (get_parm (0, response, "Convert file? ", 1, "Y"))
- if (get_parm (1, response2, "Delete buffer? ", 1, "Y"))
- { int file_is_hex;
- file_is_hex = 0;
- buf_to_edit = inq_buffer (); // Store the current buffer id
- raise_anchor (); // Remove the highlight
- if (inq_modified ()) // Only write and convert if changed
- {
- returns write_buffer (); // Preserve the return value
- file_was_modified = 1;
- }
- else
- file_was_modified = 0; // if not changed don't reconvert
- // Remove the extension.
- if (index (file_name, "."))
- file_name = substr (file_name, 1, rindex (file_name, ".") - 1);
- // Make the system buffer database current
- if (ext == "hex")
- {
- set_buffer (__hex_files);
- file_is_hex = 1;
- }
- else
- set_buffer (__unix_files); // Not used in this example
- top_of_buffer ();
- // Try to find filename record and extract original extension.
- if (search_fwd (file_name + ",ext=", 0, 0))
- { beginning_of_line ();
- ext = trim (read ());
- file_is_controlled=1;
- // Find the ascii buffer associated with the hex buffer
- if (file_is_hex)
- { int temp_buffer=inq_buffer();
- ext = ltrim (substr (ext, index (ext, "newb=") + 5));
- old_buffer = substr (ext, 1, 10);
- // Retrieve the buffer id
- buf_to_delete = atoi (old_buffer, 1);
- set_buffer(buf_to_delete);
- raise_anchor();
- write_buffer();
- drop_anchor(2);
- set_buffer(temp_buffer);
- if (upper (response2) == "Y")
- delete_buffer (buf_to_delete);
- }
- ext = trim (substr (ext, rindex (ext, "=") + 1));
- beginning_of_line ();
- if (upper (response2) == "Y")
- delete_line (); // Delete the record
- }
- // Reset the current buffer
- set_buffer (buf_to_edit);
- if (file_is_hex)
- sprintf (write_command, "bbe HB %s.hex %s.%s>&nul", file_name,
- file_name, ext);
- else
- sprintf (write_command, "bbe DU %s.unx %s.%s>&nul", file_name,
- file_name, ext);
- if (file_was_modified && upper (response) == "Y" &&
- file_is_controlled)
- {
- message ("%s", write_command);
- dos (write_command); // Call DOS to execute the conversion
- message ("Conversion complete");
- }
- // Delete the current buffer and the converted file(s).
- if (upper (response2) == "Y")
- {
- if (1 != delete_curr_buffer())
- {
- file_is_controlled=-1;
- delete_buffer(buf_to_edit);
- }
- if (file_is_hex)
- {
- sprintf (response, "%s.hex", file_name);
- del (response);
- sprintf (response, "%s.asc", file_name);
- }
- else
- sprintf (response, "%s.unx", file_name);
- del (response);
- if (file_is_controlled == -1) // No other buffers
- exit("y");
- }
- else
- if (file_is_hex && file_is_controlled)
- {
- move_rel (0, -1);
- drop_anchor ();
- move_rel (0, 1);
- }
- }
- else ;
- else ;
- else // Call the primitive
- return write_buffer ();
- }
-
-
- [LISTING TWO]
-
- /* _bin_add _bin_atoh add_hex_keys _bin_edit _bin_delete */
-
- // _bin_move -- this macro handles synchronized positioning.
- void _bin_move (int direction)
- { int col, line;
- get_parm(0,direction);
- raise_anchor ();
- unregister_macro (1, "_call_on_packages"); // Remove the language control
- set_window (__asc_window);
- raise_anchor ();
- inq_position (line, col);
- switch (direction)
- { case LEFT:
- case RIGHT:
- {
- if ((col == 25 && direction == RIGHT) || (col==1 && direction==LEFT))
- { // Scrolling is needed
- move_rel (direction,0);
- col = (direction == LEFT ? 25 : 1);
- move_abs (0,col);
- }
- else
- move_rel (0,direction);
- }
- case UP:
- case DOWN:
- move_rel (direction % 10,0);
- case PGUP:
- case PGDN:
- { inq_window_size(line); // Get the number of lines in the window
- move_rel ((direction % 20) * line,0);
- }
- case HOME:
- move_abs(0,1); // Beginning of line
- case END:
- move_abs(0,25); // End of line
- case TOP:
- move_abs(1,1); // Top of buffer
- case BOTTOM:
- { end_of_buffer();
- move_abs(0,25); // End of buffer
- }
- }
- while (inq_position (line,col)) // We might be in virtual space if
- move_rel (-1, 0); // so move up until we're not.
- drop_anchor (2);
- refresh ();
- set_window (__hex_window);
- move_abs(line,col * 2); // Reposition in the hex buffer
- move_rel (0, -1); // Highlight the current byte.
- drop_anchor ();
- move_rel (0, 1);
- refresh ();
- register_macro (1, "_call_on_packages");
- }
- // _bin_add: overwrites the byte in hex window. It is assigned to all of valid
- // hex editing keys and uses push_back to get the original key.
- void _bin_add (string key_read)
- { string character, sread;
- int hex_val, temp_hex;
- // Get the parameter which is key pressed and push it back on keyboard
- // buffer so that it displays in prompt as if it were typed there.
- get_parm (0, key_read);
- push_back (key_to_int (key_read));
- raise_anchor ();
- // Read the text from the buffer to display the old value at the prompt.
- move_rel (0, -1);
- sread = "Enter new value for ";
- if (read (1) != "\n")
- sread += read (2);
- sread += ": ";
- if (get_parm (1, character, sread, 2))
- { // Limit the prompt response to two characters
- hex_val = _bin_atoh(character);
- sprintf (character, "%02x", hex_val); // Convert the int to hex.
- unregister_macro (1, "_call_on_packages"); // Don't disturb the windows.
- set_window (__asc_window);
- switch (hex_val) // Make sure the value typed is displayable
- { case 13:
- case 9:
- case 0:
- sread = ".";
- default:
- sprintf (sread, "%c", hex_val);
- }
- raise_anchor ();
- delete_char (); // Remove the old character and insert the new.
- insert ("%s", sread);
- move_rel(0,-1);
- drop_anchor (2);
- refresh ();
- set_window (__hex_window);
- delete_char (2); // Remove the old byte and insert the new.
- insert ("%s", upper (character));
- }
- drop_anchor ();
- move_rel (0, 1);
- refresh ();
- register_macro (1, "_call_on_packages"); // Reenable the language macro
- refresh ();
- execute_macro(inq_assignment("<Right>")); // Move to the next byte.
- }
- // _bin_delete: converts the current byte to XX which will be ignored when
- // reconverted. Parameter is for deleting a full line.
- void _bin_delete (~int line)
- { get_parm(0,line);
- unregister_macro (1, "_call_on_packages");
- set_window (__asc_window);
- raise_anchor ();
- if (line)
- { save_position();
- move_abs(0,1);
- drop_anchor(3);
- translate("?",".",1,1,1,1); // Change any character to a "."
- raise_anchor ();
- restore_position();
- }
- else
- { delete_char ();
- insert (".");
- move_rel (0, -1);
- }
- drop_anchor (2);
- refresh ();
- set_window (__hex_window);
- raise_anchor ();
- if (line)
- { save_position();
- move_abs(0,1);
- drop_anchor(3);
- translate("?","X",1,1,1,1); // Change any character to "X"
- raise_anchor ();
- restore_position();
- move_rel (0, -1);
- }
- else
- { move_rel (0, 1);
- insert ("XX");
- move_rel (0, -4);
- delete_char (2);
- }
- drop_anchor ();
- move_rel (0, 1);
- register_macro (1, "_call_on_packages");
- refresh ();
- }
- // _bin_atoh -- accepts a "hex" string and returns an integer.
- int _bin_atoh (string to_convert)
- { string str_rev;
- int converted, loop_count, t_int;
-
- get_parm (0, to_convert);
-
- // Read a character from the end of the string and multiply
- // it by the loop count which is multiplied by 16 on each iteration.
- while (strlen (trim (to_convert)))
- { str_rev = substr (to_convert, strlen (to_convert), 1);
- t_int = index("123456789ABCDEF",upper(str_rev));
- loop_count *= 16;
- if (0 == loop_count)
- loop_count = 1;
- converted += t_int * loop_count;
- to_convert = substr (to_convert, 1, strlen (to_convert) - 1);
- }
- return converted;
- }
- // add_hex_keys -- adds hex editing keys to the keyboard.
- add_hex_keys()
- { string macro_name, key_name;
- int loop;
- for (loop=48; loop<58; loop++) // Assign the numeric keys
- { // to the keyboard
- sprintf (key_name, "<%c>",loop);
- sprintf (macro_name, "_bin_add \"%c\"",loop);
- assign_to_key (key_name, macro_name);
- }
- for (loop=65;loop<71;loop++) // Assign the a-f Hex keys
- { // to the keyboard
- sprintf (key_name, "<%c>",loop);
- sprintf (macro_name, "_bin_add \"%c\"",loop);
- assign_to_key (key_name, macro_name);
- assign_to_key (lower(key_name), macro_name);
- }
- assign_to_key ("<Alt-n>", "edit_next_buffer");
- assign_to_key ("<Alt-e>", "edit_file");
- assign_to_key ("<Alt-w>", "write_buffer");
- assign_to_key ("<Alt-x>", "exit");
- sprintf (macro_name, "_bin_move %d", UP);
- assign_to_key ("<Up>", macro_name);
- sprintf (macro_name, "_bin_move %d", DOWN);
- assign_to_key ("<Keypad-Enter>", macro_name);
- assign_to_key ("<Down>", macro_name);
- sprintf (macro_name, "_bin_move %d", LEFT);
- assign_to_key ("<Left>", macro_name);
- sprintf (macro_name, "_bin_move %d", RIGHT);
- assign_to_key ("<Right>", macro_name);
- sprintf (macro_name, "_bin_move %d", PGUP);
- assign_to_key ("<PgUp>", macro_name);
- sprintf (macro_name, "_bin_move %d", PGDN);
- assign_to_key ("<PgDn>", macro_name);
- sprintf (macro_name, "_bin_move %d", TOP);
- assign_to_key ("<Ctrl-Pgup>", macro_name);
- sprintf (macro_name, "_bin_move %d", BOTTOM);
- assign_to_key ("<Ctrl-PgDn>", macro_name);
- sprintf (macro_name, "_bin_move %d", HOME);
- assign_to_key ("<Home>", macro_name);
- sprintf (macro_name, "_bin_move %d", END);
- assign_to_key ("<End>", macro_name);
- }
- // _bin_edit -- registered macro for trapping Null files message.
- void _bin_edit ()
- { if (inq_message () == "Null characters in file fixed.")
- { string okay;
- string file;
- inq_names (file);
- // See if the conversion is requested.
- if (get_parm (0, okay, "Okay to create HEX file to edit? ", 1, "Y"))
- if (upper (okay) == "Y")
- _hex_edit (file, 0); // Call _hex_edit to do conversion
- else // Other wise let the user frustrate themselves.
- message ("You asked for it.");
- }
- }
- on_packages"); // Don't disturb the windows.
- set_window (__asc_window);
-